package com.dragon.common.spring.openapi.customizers.operation;

import com.dragon.common.spring.annotations.ApiOrder;
import io.swagger.v3.oas.models.Operation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springdoc.core.customizers.OperationCustomizer;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;

/**
 * @author Chris Chan
 * Create On 2025/10/2 上午11:23
 * Use for: 为Operation添加排序
 * Explain: 排序值越小，越靠前
 */
@Component
public class TagOrderOperationCustomizer implements OperationCustomizer {

    private static final Logger log = LoggerFactory.getLogger(TagOrderOperationCustomizer.class);

    @Override
    public Operation customize(Operation operation, HandlerMethod handlerMethod) {
        // 获取处理方法的 Bean 类型
        Class<?> beanType = handlerMethod.getBeanType();

        // 查找类上的 @ApiOrder 注解（按优先级：实现类 -> 父类 -> 接口 -> 父类的接口）
        Integer orderValue = findOrderValue(beanType);

        if (orderValue != null) {
            // 将 order 值存储为扩展属性
            operation.addExtension("x-tag-order", orderValue);

            // 获取 tag 名称（通常第一个 tag）
            if (operation.getTags() != null && !operation.getTags().isEmpty()) {
                String tagName = operation.getTags().get(0);
                operation.addExtension("x-tag-name", tagName);

                //log.debug("为 Tag '{}' 设置 Order: {}", tagName, orderValue);
            }
        }

        // 2025-10-03 新增功能：给path排序
        ApiOrder pathOrder = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), ApiOrder.class);
        if (pathOrder != null) {
            operation.addExtension("x-path-order", pathOrder.value());
        }

        return operation;
    }

    /**
     * 按优先级查找 Order 值
     * 优先级：实现类 -> 父类 -> 接口 -> 父类的接口
     */
    private Integer findOrderValue(Class<?> clazz) {
        // 1. 检查当前类
        ApiOrder order = AnnotationUtils.findAnnotation(clazz, ApiOrder.class);
        if (order != null) {
            return order.value();
        }

        // 2. 检查父类
        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null && superClass != Object.class) {
            Integer superOrder = findOrderValue(superClass);
            if (superOrder != null) {
                return superOrder;
            }
        }

        // 3. 检查接口
        for (Class<?> interfaceClass : clazz.getInterfaces()) {
            Integer interfaceOrder = findOrderInInterface(interfaceClass);
            if (interfaceOrder != null) {
                return interfaceOrder;
            }
        }

        return null;
    }

    /**
     * 在接口及其父接口中查找 Order
     *
     * @param interfaceClass
     * @return
     */
    private Integer findOrderInInterface(Class<?> interfaceClass) {
        // 检查当前接口
        ApiOrder order = AnnotationUtils.findAnnotation(interfaceClass, ApiOrder.class);
        if (order != null) {
            return order.value();
        }

        // 递归检查父接口
        for (Class<?> parentInterface : interfaceClass.getInterfaces()) {
            Integer parentOrder = findOrderInInterface(parentInterface);
            if (parentOrder != null) {
                return parentOrder;
            }
        }

        return null;
    }
}